	
	/************************************************************************************************
	 	
	 	Factory: jsl.Array
	 	
		Constructors:
			a			Array				(a*)							- sid: 7.0
			a			replicate		(n, v*)						- sid: 7.0
																														
		Slicers:
			a			after				(v, n*, idx*)			- sid: 7.0
			a			before			(v, n*, idx*)			- sid: 7.0
			v			last				()								- sid: 7.0
			a			left				(n)								- sid: 7.0
			a			right				(n)								- sid: 7.0

		Info:	
			b			contains		(v, idx*)					- sid: 7.0
			n			index				(v, n*, idx*)			- sid: 7.0
      b     isUnique    ()								- sid: 7.0
			b			intersects	(a)								- sid: 7.0
	
		Operations:
			n			count				(v, idx*)					- sid: 7.0
			n			sum					(idx*)						- sid: 7.0			
			a			unique			(right*)					- sid: 7.0					
			a			intersecate (a)								- sid: 7.0
			a			union				(a)								- sid: 7.0
			a			less				(a)								- sid: 7.0
		
		Modifiers:
			a			inject			(v, idx*)					- sid: 7.0
			a			include			(v, idx*)					- sid. 7.0
			a			modify			(v, v2, n*, idx*)	- sid: 7.0
			a			remove			(v, n*, idx*)			- sid: 7.0 	
			a			removeAt		(idx, n*)					- sid: 7.0
																			
		Overriding(no in the site):
			it		getIterator	(filter)					- sid: .0
								
	************************************************************************************************/
	
  //-------------------------------------------------------------------------------
  jsl.Array = function(a) {
  	try {  		
  		var proto, rv
  		//@d[
	    if(arguments.length > 1) 	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(a, "a")//@d]
			
			if(arguments.length)
				if(a.__augmented) return a
				else							rv = a
			else
				rv = new Array
													    			 	    	    
			proto = jsl.Array.prototype
			
    	for(var id in proto)
    		if(proto.hasOwnProperty(id))
					rv[id] = proto[id]

			rv.__native = arguments.callee.__native						
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
  }
  //-------------------------------------------------------------------------------
	jsl.Array.__name		= "jsl.Array" 
	jsl.Array.prototype	= jsl.Object()
  //-------------------------------------------------------------------------------
	jsl.Array.replicate = function(n, v) {
		try {			
			var rv
			
			//@d[
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			jsl.validate(n,"i+", "n")//@d]
			
			rv = Array(n)
			
			if(v !== undefined)
				for(var a = 0, l = rv.length; a < l; a++)
					rv[a] = v
			
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.after = function(v, n, idx) {
		try {			
			var i
			
			//@d[
			if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 3) throw jsl.ParamError()
			if(arguments.length >= 2) 										jsl.validate(n	, "i!0"	, "n")
			if(arguments.length === 3) 										jsl.validate(idx, "i+"	, "idx")//@d]
			
			i = jsl.Array.prototype.index.apply(this, arguments)

			return i !== -1 ? this.slice(i + 1) : []
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.before = function(v, n, idx) {
		try {
			var i
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 3) throw jsl.ParamError()
			if(arguments.length >= 2) 										jsl.validate(n	, "i!0"	, "n")
			if(arguments.length === 3) 										jsl.validate(idx, "i+"	, "idx")//@d]
			
			i = jsl.Array.prototype.index.apply(this, arguments)
			
			return i !== -1 ? this.slice(0, i) : this.slice()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.last = function() {
		try {			
			//@d[
      if(!jsl.isArray(this))	throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length) 		throw jsl.ParamError()//@d]
			
			
			return this.length ? this[this.length - 1] : null
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.left = function(n) {
		try {
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(n, "i", "n")//@d]
						
			return this.slice(0, n)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.right = function(n) {
		try {			
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(n, "i", "n")//@d]

			return n != 0 ? this.slice(-n) : []
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.contains = function(v, idx) {
		try {
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			if(arguments.length === 2) 										jsl.validate(idx, "i+"	, "idx")//@d]
						
			return jsl.Array.prototype.index.call(this, v, 1, idx || 0) !== -1
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.index = function(v, n, idx) {
		try {
			var i, ix, rv, a, l
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 3) throw jsl.ParamError()
			if(arguments.length >= 2 && n != "*")					jsl.validate(n	, "i!0"	, "n")
			if(arguments.length === 3) 										jsl.validate(idx, "i+"	, "idx")//@d]
			
			i 	= +n		|| 1
			ix	= +idx	|| 0
			rv	= -1

			if(n == "*") {			
				
				rv = []
				
				for(a = ix, l = this.length; a < l; a++)
					if(this[a] === v)
						rv.push(a)
				
				rv = rv.length ? rv : null		
			}
			else if(i < 0) {			
				for(a = this.length - 1; a >= ix && rv === -1; a--)
					if(this[a] === v && !++i)
						rv = a
			}
			else
				for(a = ix, l = this.length; a < l && rv === -1; a++)
					if(this[a] === v && !--i)
						rv = a
						
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.isUnique = function() {
		try {
			//@d[
      if(!jsl.isArray(this))	throw jsl.TypeError("BadMethodCall:Array")			
			if(arguments.length) 		throw jsl.ParamError()//@d]
						
			loop:
			for(var a = 0, l = this.length; a < l; a++)
				for(var b = a + 1; b < l; b++) 
					if(this[a] === this[b])
						break loop
			
			return a === l			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.intersects = function(a) {
		try {
			var i
			
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(a, "al", "a")//@d]

			for(var b = 0, l = a.length; b < l && !i; b++)				 
				i	= jsl.Array.prototype.index.call(this, a[b]) !== -1					
			
			return !!i
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}				
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.count = function(v, idx) {
		try {
			var n
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			if(arguments.length === 2) 										jsl.validate(idx, "i+"	, "idx")//@d]
			
			n = 0
			
			for(var a = +idx || 0, l = this.length; a < l; a++) 
				if(this[a] === v)
					n++
			
			return n
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.sum = function(idx) {
		try {
			var n
			
			//@d[
      if(!jsl.isArray(this))		throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length > 1) 	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(idx, "i+", "idx")//@d]
			
			n = 0
			
			for(var a = +idx || 0, l = this.length; a < l; a++)
				n += +this[a]
				
			return n
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.unique = function(right) {
		try {
			var a, l, v, i

			//@d[
      if(!jsl.isArray(this))		throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length > 1) 	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(right, "b"	, "right")//@d]
						
			v 	= []
			i		= jsl.Array.prototype.index
						
			//right
			//-----------------------------------------------------------------------				
			if(right) { 				
				for(a = this.length - 1; a >= 0; a--) 				
					if(i.call(v, this[a]) === -1) 
						v.unshift(this[a])		
			}
			//left
			//-----------------------------------------------------------------------				
			else 
				for(a = 0, l = this.length; a < l; a++) 							
					if(i.call(v, this[a]) === -1) 
						v.push(this[a])		
				
			return v			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.intersecate = function(a) {
		try {
			var v
			
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(a, "al", "a")//@d]
			
			v = []
			
			for(var b = 0, l = this.length; b < l; b++) 
				for(var c = 0, l2 = a.length; c < l2; c++) 									
					if(a[c] === this[b]) {
						v.push(this[b])
						break
					}
					
			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.union = function(a) {
		try {
			var v, i, b, l
			
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(a, "al", "a")//@d]

			v = this.slice()
			i	= jsl.Array.prototype.index
							
			for(b = 0, l = a.length; b < l; b++) 
				if(i.call(v, a[b]) === -1)	
					v.push(a[b])

			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.less = function(a) {
		try {
			var v, i, ix, b
			
			//@d[
      if(!jsl.isArray(this))			throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length !== 1) 	throw jsl.ParamError()
			jsl.validate(a, "al", "a")//@d]

			v = this.slice()
			i	= jsl.Array.prototype.index
									
			for(b = a.length - 1; b >= 0; b--) {				

				ix = i.call(v, a[b])
				if(ix !== -1)	
					v.splice(ix, 1)
			}
					
			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}				
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.inject = function(v, idx) {
		try {
			var args, i
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			if(arguments.length === 2)										jsl.validate(idx,"i+", "idx")//@d]
			
			i = arguments.length === 2 ? +idx : this.length
				
			if(v instanceof Array) {
				
				//@sys: v8Cgi 0.9.0 - RangeError: Maximum call stack size exceeded (too many arguments)
				for(var a = 0, l = v.length; a < l; a += 20000) {
					
					args = [i + a * 20000, 0].concat(v.slice(a, a + 20000)) 
					this.splice.apply(this, args)					
				}
			}
			else
				this.splice(i, 0, v)
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.include = function(v, idx) {
		try {
			var i, ix
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")			
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			if(arguments.length === 2)										jsl.validate(idx,"i+", "idx")//@d]

			i 	= arguments.length === 2 ? +idx : this.length
			ix	= jsl.Array.prototype.index
				
			if(v instanceof Array) {
				
				for(var a = 0, l = v.length; a < l; a++) 
					if(ix.call(this, v[a]) === -1)					
						this.splice(i++, 0, v[a])					
			}
			else if(ix.call(this, v) === -1)
				this.splice(i, 0, v)
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.modify = function(v, v2, n, idx) {
		try {			
			var ix, ind, i
			
			//@d[
      if(!jsl.isArray(this))														throw jsl.TypeError("BadMethodCall:Array")
			if(arguments.length < 2 || arguments.length > 4) 	throw jsl.ParamError()
			if(arguments.length >= 3 && n != "*") 						jsl.validate(n	, "i!0"	, "n")
			if(arguments.length === 4)												jsl.validate(idx, "i+"	, "idx")//@d]

			ix 	= arguments.length === 4 ? +idx : 0
			ind	= jsl.Array.prototype.index
						
			if(n == "*") {

				for(var a = this.length - 1; a >= ix; a--)
					if(this[a] === v)
						this.splice(a, 1, v2)
			}
			else {
				
				i = arguments.length >= 3 ? +n : 1
				i = ind.call(this, v, i, ix)
				
				if(i !== -1)
					this.splice(i, 1, v2)
			}			
				
			return this						
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.remove = function(v, n, idx) {
		try {
			var ix, ind, i
			
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 3)	throw jsl.ParamError()
			if(arguments.length >= 2 && n != "*") 				jsl.validate(n	, "i!0"	, "n")
			if(arguments.length === 3)										jsl.validate(idx, "i+"	, "idx")//@d]
			
			ix 	= +idx || 0
			ind	= jsl.Array.prototype.index
			
			if(n == "*") {
				
				for(var a = this.length - 1; a >= ix; a--)
					if(this[a] === v)
						this.splice(a, 1)				
			}			
			else {
			
				i = +n || 1
				i = ind.call(this, v, i, ix)
				
				if(i !== -1)
					this.splice(i, 1)
			}
				
			return this						
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}			
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.removeAt = function(idx, n) {
		try {
			//@d[
      if(!jsl.isArray(this))												throw jsl.TypeError("BadMethodCall:Array")
			if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
			jsl.validate(idx, "i+", "idx")
			if(arguments.length === 2)										jsl.validate(n,"i+", "n")//@d]

			this.splice(idx, arguments.length === 2 ? +n : 1)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Array.prototype.getIterator = function(filter) {
		try {
    	var it, idx, obj
    	//@d[    	    	
      if(!jsl.isArray(this))		throw jsl.TypeError("BadMethodCall:Array")			
      if(arguments.length > 1)	throw jsl.ParamError()
      if(arguments.length)      jsl.validate(filter, "f", "filter")//@d]
			
			it 			= { __name: "jsl.ArrayIterator" }
			obj			= this
			idx			= 0
						 
  		//-------------------------------------------------------------------------------
			it.hasNext = function() {
				try {//@d[
					if(arguments.length)	throw jsl.ParamError()//@d]
										
					while(idx < obj.length) {
						
						if(filter ? filter.call(obj, idx + "", obj[idx]) : true)						
							break
						
						idx++
					}

					return idx < obj.length
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
  		//-------------------------------------------------------------------------------
			it.next = function() {
				try {//@d[
					if(arguments.length) throw jsl.ParamError()//@d]
					
					var b = this.hasNext()
					//@d[					
					if(!b)	throw jsl.EndOfIterationError()//@d]
					return obj[idx++]
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
												
      return it
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//Array init
	//-------------------------------------------------------------------------------
	;(function() {
		
		var proto
				
		//-------------------------------------------------------------------------------
		jsl.Array.__native	= jsl.Object.__native.copy().merge(jsl.Array.prototype)
		proto 							= jsl.Array.prototype
		
		for(var id in proto) 
			if(proto.hasOwnProperty(id)) 
				if(id.charAt(0) !== "_" && jsl.isFunction(proto[id]) && !proto[id].__name) {
					
					jsl.Array[id] = function(obj) { 
						try {
							//@d[
							if(!arguments.length)	throw jsl.ParamError() 
							if(obj === null)			throw jsl.ParamError("NullValue:obj")
							//@d]
							
							return arguments.callee.__f.apply(obj, Array.prototype.slice.call(arguments, 1)) 
						}
						catch(e) {
							jsl.throwError(e, this, arguments)
						}
					}
						
					jsl.Array[id].__name	= id
					jsl.Array[id].__f			= proto[id]
					proto[id].__name 			= id
				}									
	})()
